Terraform과 Cloud-init으로 Proxmox 모니터링 VM 자동 배포
1줄 요약
Terraform과 cloud-init을 이용해 Proxmox VM을 생성하고, VM 부팅 시 Docker Compose로 Prometheus, Grafana, Loki 모니터링 스택을 자동으로 배포하는 구성입니다.
개요
Proxmox 환경에서 다수의 테스트용 가상 머신을 운영하기 위한 기반 모니터링 시스템을 Terraform으로 자동 구축합니다. 이 구성은 vm1-monitor라는 특정 VM에 Prometheus, Grafana, Loki, Node Exporter 스택을 Docker Compose를 통해 배포하는 과정을 cloud-init으로 자동화하는 것을 목표로 합니다.
VM 환경 정의
Terraform 변수를 사용하여 프로젝트에 필요한 전체 VM 목록과 각각의 사양, 역할을 정의합니다. 이 중 vm1-monitor가 모니터링 스택이 설치될 대상입니다.
terraform
variable "lab_vms" {
default = {
"vm1-monitor" = { vmid = 501, cores = 2, memory = 2048, ip = "", role = "monitor" }
"vm2-lb" = { vmid = 502, cores = 1, memory = 1024, ip = "", role = "node" }
"vm3-web1" = { vmid = 503, cores = 1, memory = 1024, ip = "", role = "node" }
"vm4-web2" = { vmid = 504, cores = 1, memory = 1024, ip = "", role = "node" }
"vm5-data" = { vmid = 505, cores = 1, memory = 2048, ip = "", role = "node" }
}
}Cloud-init을 이용한 VM 프로비저닝 자동화
proxmox_virtual_environment_file 리소스를 사용해 Proxmox의 스니펫 기능으로 cloud-init 설정 파일을 업로드합니다. 이 파일은 모니터링 VM이 생성될 때 자동으로 실행되어 시스템 초기 설정부터 모니터링 애플리케이션 배포까지 모든 과정을 처리합니다.
terraform
resource "proxmox_virtual_environment_file" "monitor_user_data" {
content_type = "snippets"
datastore_id = "local"
node_name = "localhost"
source_raw {
data = <<-EOF
#cloud-config
hostname: vm1-monitor
fqdn: vm1-monitor.lab
manage_etc_hosts: true
users:
- name: root
ssh_authorized_keys:
- "ssh-ed25519..."
chpasswd:
list: |
root:password
expire: false
package_update: true
packages:
- curl
- tar
- wget
- dnf-plugins-core
write_files:
- path: /opt/monitoring/prometheus.yml
permissions: '0644'
content: |
global:
scrape_interval: 5s
scrape_configs:
- job_name: 'proxmox-cluster'
static_configs:
- targets: ['10.0.0.100:9100']
labels:
instance: 'vm1-monitor'
- targets: ['10.0.0.101:9100']
labels:
instance: 'vm2-lb'
- targets: ['10.0.0.102:9100']
labels:
instance: 'vm3-web1'
- targets: ['10.0.0.103:9100']
labels:
instance: 'vm4-web2'
- targets: ['10.0.0.104:9100']
labels:
instance: 'vm5-data'
- path: /opt/monitoring/provisioning/datasources/datasources.yml
permissions: '0644'
content: |
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
- name: Loki
type: loki
access: proxy
url: http://loki:3100
- path: /opt/monitoring/docker-compose.yml
permissions: '0644'
content: |
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: always
volumes:
- /opt/monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
ports:
- "9090:9090"
networks:
- monitoring
loki:
image: grafana/loki:latest
container_name: loki
restart: always
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
networks:
- monitoring
grafana:
image: grafana/grafana:latest
container_name: grafana
restart: always
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- /opt/monitoring/provisioning/datasources:/etc/grafana/provisioning/datasources
networks:
- monitoring
node_exporter:
image: prom/node-exporter:latest
container_name: node_exporter
restart: always
network_mode: host
pid: host
volumes:
- /:/host:ro,rslave
command:
- --path.rootfs=/host
networks:
monitoring:
driver: bridge
runcmd:
- systemctl stop firewalld || true
- systemctl disable firewalld || true
- dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
- dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
- systemctl enable --now docker
- docker compose -f /opt/monitoring/docker-compose.yml up -d
EOF
file_name = "user-data-monitor.yaml"
}
}구성 분석
- 초기 시스템 설정:
hostname,users,packages등의 모듈을 통해 VM의 기본 정보를 설정하고 필수 패키지를 설치합니다. - 설정 파일 생성 (
write_files):prometheus.yml: Prometheus가 수집할 대상(target)을 정적으로 정의합니다.vm1-monitor자신을 포함한 모든 랩 VM의node-exporter엔드포인트(:9100)가 명시되어 있습니다.datasources.yml: Grafana의 프로비저닝 기능을 활용하여, Grafana가 시작될 때 Prometheus와 Loki를 데이터 소스로 자동 등록하도록 설정합니다.docker-compose.yml: 모니터링 스택을 구성하는 각 서비스(Prometheus, Loki, Grafana, Node Exporter)를 정의합니다.monitoring브리지 네트워크를 통해 서비스 간 통신이 이루어집니다. 특히node_exporter는network_mode: host로 설정하여 컨테이너가 아닌 호스트 VM 자체의 시스템 메트릭을 수집합니다.
- 서비스 실행 (
runcmd):- 방화벽(firewalld)을 비활성화합니다.
- Docker CE 리포지토리를 추가하고 Docker 및 Docker Compose를 설치합니다.
- Docker 서비스를 활성화하고,
write_files단계에서 생성한docker-compose.yml파일을 이용해 모든 모니터링 서비스를 백그라운드에서 실행합니다.
핵심 체크포인트 (Gotchas)
- Cloud-init 활용: VM 생성과 동시에 패키지 설치, 설정 파일 주입, 서비스 실행까지 단일 워크플로우로 처리하여 인프라 프로비저닝을 완벽하게 자동화할 수 있습니다.
- Node Exporter의 Host 모드:
network_mode: host와pid: host옵션은node_exporter가 컨테이너 내부가 아닌 호스트 VM의 네트워크 및 프로세스 정보를 직접 접근하여 정확한 시스템 메트릭을 수집하기 위한 필수 설정입니다. - Grafana 자동 프로비저닝:
volumes를 통해datasources.yml설정 파일을 컨테이너 내 특정 경로에 마운트하면, Grafana 실행 시 수동 설정 작업 없이도 즉시 데이터 소스를 사용할 수 있어 배포 편의성이 크게 향상됩니다.